package com.coffee.framework.security.handler;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.ContentType;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import cn.hutool.json.JSONUtil;
import com.coffee.common.Constants;
import com.coffee.common.bo.LoginUser;
import com.coffee.common.enums.LogStatusEnum;
import com.coffee.common.enums.UserPlatformEnum;
import com.coffee.common.result.R;
import com.coffee.common.util.AddressUtil;
import com.coffee.common.util.IpUtil;
import com.coffee.framework.web.service.ITokenService;
import com.coffee.system.entity.SysLog;
import com.coffee.system.service.ISysLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;


/**
 * 自定义退出拦截器
 *
 * @author Kevin
 */
@Component
@Slf4j
public class CustomLogoutSuccessHandler implements LogoutSuccessHandler {

    @Resource
    private ITokenService tokenService;

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        String token = request.getHeader(Constants.HEADER_TOKEN);
        if (StrUtil.isNotBlank(token)) {
            LoginUser loginUser = tokenService.getUserByToken(token);
            if (Objects.nonNull(loginUser)) {
                String ipAddress = IpUtil.getClientIp(request);
                log.info("ip：{}， 用户：{}，在{}退出了系统，在线时长：{}",
                        ipAddress,
                        loginUser.getUsername(),
                        DateUtil.now(),
                        DateUtil.formatBetween(loginUser.getLoginTime(), DateUtil.date()));
                recordLogoutLog(LogStatusEnum.SUCCESS.getCode(), loginUser);
            }
            tokenService.deleteToken(token);
        }
        response.setCharacterEncoding(CharsetUtil.UTF_8);
        ServletUtil.write(response, JSONUtil.toJsonStr(R.success("退出成功")), ContentType.JSON.toString());
    }

    public void recordLogoutLog(String logStatus, LoginUser loginUser) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        SysLog sysLog = new SysLog();
        sysLog.setTitle("退出系统");
        sysLog.setLogStatus(LogStatusEnum.SUCCESS.getCode());
        sysLog.setUserPlatform(UserPlatformEnum.WEB.getCode());
        sysLog.setRequsetUri(request.getRequestURI());
        sysLog.setRequsetType(request.getMethod());
        sysLog.setRequsetMethod(null);
        sysLog.setRequsetParams(null);
        sysLog.setResponseResult(null);
        sysLog.setRequsetTime(null);

        String ipAddress = IpUtil.getClientIp(request);
        sysLog.setIpAddress(ipAddress);
        sysLog.setOperLocation(AddressUtil.getRealAddressByIp(ipAddress));
        UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
        sysLog.setBrowser(userAgent.getBrowser().getName());
        sysLog.setOs(userAgent.getOs().getName());

        sysLog.setOperName(loginUser.getUsername());

        sysLog.setLogStatus(logStatus);
        sysLog.setException(null);

        ThreadUtil.execAsync(() -> {
            ISysLogService sysLogService = SpringUtil.getBean(ISysLogService.class);
            sysLogService.save(sysLog);
        });
    }

}
